﻿using OF.Utility.DataAccess.Entity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;

namespace OF.Utility.DataAccess.DbProvider
{
    public class DBConfigHelper
    {
        public static DBConfig ConfigSetting
        {
            get
            {
                return CacheManager.GetWithCache("OF_DataAccess_DBConfig", _LoadConfig, int.MaxValue);
                //return _LoadConfig();
            }
        }

        private static object _obj = new object();
        private static DBConfig _LoadConfig()
        {
            lock (_obj)
            {
                string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Configuration\Data\DB.config");
                if (File.Exists(filePath))
                {
                    DBConfig config = SerializeHelper.LoadFromXml<DBConfig>(filePath);
                    foreach(DBConnection con in  config.DBConnectionList)
                    {
                        if(!string.IsNullOrWhiteSpace(con.IsEncrypt)
                            && (con.IsEncrypt.Trim().ToUpper()=="Y" ||con.IsEncrypt.Trim().ToUpper()=="YES"))
                        {
                            con.ConnectionString = CryptoManager.Decrypt(con.ConnectionString);
                           
                        }
                    }

                    if (config.DBConnectionRoute != null && config.DBConnectionRoute.RouteConnections != null)
                    {
                        var writeRouteConnections = config.DBConnectionRoute.RouteConnections.FindAll(
                            r => string.Equals(r.IsWrite, "true", StringComparison.InvariantCultureIgnoreCase) ||
                                 string.Equals(r.IsWrite, "yes", StringComparison.InvariantCultureIgnoreCase) ||
                                 string.Equals(r.IsWrite, "y", StringComparison.InvariantCultureIgnoreCase) ||
                                 string.Equals(r.IsWrite, "1", StringComparison.InvariantCultureIgnoreCase));

                        foreach (DBConnectionRoute.RouteConnection routeConnection in writeRouteConnections)
                        {
                            var q = from n in routeConnection.Nodes
                                group n by n.SplitDbCode
                                into g
                                select new {SplitDbCode = g.Key, Nums = g.Count()};

                            foreach (var r in q)
                            {
                                if (r.Nums > 1)
                                {
                                    if (string.IsNullOrWhiteSpace(r.SplitDbCode))
                                        throw new NotSupportedException(
                                            string.Format("DB.config error, Connection Key {0} is write, not support balance!",
                                                routeConnection.Key));
                                    else
                                        throw new NotSupportedException(
                                            string.Format("DB.config error, Connection Key {0} is write [SplitDbCode={1}], not support balance!",
                                                routeConnection.Key, r.SplitDbCode));
                                }
                            }

                        }
                    }
                    for (int i = 0; i < config.SQLFileList.Count;i++ )
                    {
                        string sqlFile = config.SQLFileList[i].ToUpper().Trim();
                        for(int j=i+1;j<config.SQLFileList.Count;j++)
                        {
                            string sqlFile2 = config.SQLFileList[j].ToUpper().Trim();
                            if(sqlFile==sqlFile2)
                            {
                                throw new Exception(string.Format("DB.config文件中，SQLFile \"{0}\"有重复！",sqlFile));
                            }
                        }
                    }

                        return config;
                }
                else
                {
                    throw new Exception(string.Format("Not found sql file {0}", filePath));
                }
            }
        }
    }
}
